import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:ichinesereader/exam/dto/assessment.response.dart';
import 'BGSinglePlayer.dart';

class BGExamTypeVanish extends StatelessWidget {
  final QuestionItem item;
  final Function getAnswer;

  const BGExamTypeVanish(
      {Key? key, required this.item, required this.getAnswer})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    List<Widget> widgetList = [];
    RxList<QuestionContentPlus> itemList = <QuestionContentPlus>[].obs;
    List recordList = [];
    if (item.body != null && item.body!.length > 1) {
      for (QuestionContent o in item.body!.first) {
        QuestionContentPlus plus = QuestionContentPlus();
        plus.baseValue = o.baseValue;
        plus.show = o.show;
        plus.text = o.text;
        plus.audio = o.audio;
        plus.image = o.image;
        plus.color = Color(Random().nextInt(0xffffffff)).withAlpha(0xff);
        plus.isVisible = true;
        plus.shakeColor = 0xffD9DDE8;
        itemList.add(plus);
      }
      for (QuestionContent o in item.body![1]) {
        QuestionContentPlus plus = QuestionContentPlus();
        plus.baseValue = o.baseValue;
        plus.show = o.show;
        plus.text = o.text;
        plus.audio = o.audio;
        plus.image = o.image;
        plus.color = Color(Random().nextInt(0xffffffff)).withAlpha(0xff);
        plus.isVisible = true;
        plus.shakeColor = 0xffD9DDE8;
        itemList.add(plus);
      }
      var itemWidth = 68.0;
      var itemHeight = 68.0;
      var rectList = [];
      for (int i = 0; i < itemList.length; i++) {
        String? show = itemList[i].show;
        if (show != null) {
          if (show.contains(QuestionContent.QUESTION_SHOW_TYPE_TEXT)) {
            String text = itemList[i].text ?? '';
            itemWidth = 36.0 + _paintWidthWithText(text);
          }
          if (show.contains(QuestionContent.QUESTION_SHOW_TYPE_IMAGE)) {
            itemWidth = 170;
            itemHeight = 170;
          }
        }
        var isHave = true;
        int num = 0;
        while (isHave) {
          num++;
          isHave = false;
          var x = Random()
              .nextInt(
                  (MediaQuery.of(context).size.width - 100 - itemWidth).toInt())
              .toDouble();
          var y = Random()
              .nextInt((MediaQuery.of(context).size.height - 280 - itemHeight)
                  .toInt())
              .toDouble();
          Rect itemRect = Rect.fromLTWH(x, y, itemWidth, itemHeight);
          for (int j = 0; j < rectList.length; j++) {
            if (itemRect.overlaps(rectList[j])) {
              isHave = true;
              break;
            }
          }
          if (!isHave) {
            rectList.add(itemRect);
            itemList[i].itemRect = itemRect;
            isHave = false;
          }
          if (num > 200) {
            rectList.add(itemRect);
            itemList[i].itemRect = itemRect;
            isHave = false;
          }
        }
        widgetList.add(Container(child: Obx(() {
          return Positioned(
              left: itemList[i].itemRect!.left,
              top: itemList[i].itemRect!.top,
              child: Container(
                  child: Visibility(
                visible: itemList[i].isVisible!,
                child: _buildVanishItem(
                    itemList[i], recordList, itemList, context),
              )));
        })));
      }
    }

    return Container(
        width: MediaQuery.of(context).size.width - 20,
        height: MediaQuery.of(context).size.height - 150,
        child: Stack(children: widgetList));
  }

  // 根据文字内容计算宽度
  double _paintWidthWithText(String text) {
    final TextPainter textPainter = TextPainter(
        text: TextSpan(
            text: text,
            style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
        maxLines: 1,
        textDirection: TextDirection.ltr)
      ..layout(minWidth: 0, maxWidth: double.infinity);
    return textPainter.size.width;
  }

  Widget _buildVanishItem(QuestionContentPlus body, List recordList,
      RxList<QuestionContentPlus> itemList, BuildContext context) {
    Widget option = SizedBox();
    String? show = body.show;
    Offset _offset = Offset(0, 0);
    if (show != null) {
      if (show.contains(QuestionContent.QUESTION_SHOW_TYPE_TEXT)) {
        option = Card(
            color: Colors.white,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(12),
              side: BorderSide(
                color: Color(body.shakeColor!),
                width: 2,
              ),
            ),
            child: Container(
                height: GetPlatform.isWeb?68:60,
                padding: EdgeInsets.all(15),
                alignment: Alignment.center,
                child: Text(body.text ?? '',
                    style: TextStyle(
                        fontSize: 24,
                        fontWeight: FontWeight.bold,
                        color: body.color!))));
      }
      if (show.contains(QuestionContent.QUESTION_SHOW_TYPE_AUDIO)) {
        option = Card(
            color: Colors.white,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(12),
              side: BorderSide(
                color: Color(body.shakeColor!),
                width: 2,
              ),
            ),
            child: IconButton(
              iconSize: 56,
              icon: const Icon(
                Icons.play_circle,
                color: Colors.blue,
              ),
              onPressed: () {
                BGSinglePlayer().play(body.audio);
              },
            ));
      }
      if (show.contains(QuestionContent.QUESTION_SHOW_TYPE_IMAGE)) {
        option = Card(
            color: Colors.white,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(12),
              side: BorderSide(
                color: Color(body.shakeColor!),
                width: 2,
              ),
            ),
            child: Container(
                width: 150,
                height: 150,
                padding: EdgeInsets.all(10),
                child: Image.network(body.image ?? '')));
      }
    }
    return Container(
        child: DragTarget<QuestionContentPlus>(builder: (BuildContext context,
            List<dynamic> accepted, List<dynamic> rejected) {
      return Container(
        child: Draggable<QuestionContentPlus>(
          maxSimultaneousDrags: 1,
          data: body,
          child: option,
          feedback: option,
          childWhenDragging: SizedBox(),
        ),
      );
    }, onWillAccept: (QuestionContentPlus? target) {
      return true;
    }, onMove: (details) {
      _offset = details.offset;
    }, onAccept: (QuestionContentPlus target) {
      bool isCorrect = false;
      String aStr = body.baseValue ?? '0';
      String bStr = target.baseValue ?? '0';
      int aNum = int.parse(aStr);
      int bNum = int.parse(bStr);
      if (aNum.abs() == bNum.abs() && body != target) {
        isCorrect = true;
      }
      if ((aNum == 0 || bNum == 0) ||
          (aNum > 0 && bNum > 0) ||
          (aNum < 0 && bNum < 0)) {
        isCorrect = false;
      }
      String tempStr;
      int tempNum;
      if (aNum > bNum) {
        tempNum = aNum;
        aNum = bNum;
        bNum = tempNum;
        tempStr = aStr;
        aStr = bStr;
        bStr = tempStr;
      }
      bool isHave = false;
      for (String str in recordList) {
        List tempList = str.split('|');
        if ((tempList.first == aStr ||
            tempList.first == bStr ||
            tempList.last == aStr ||
            tempList.last == bStr)) {
          isHave = true;
        }
      }
      if (!isHave) {
        recordList.add(aStr + '|' + bStr);
      }

      if (isCorrect) {
        _playVanishSound(true);
        Rect rect = target.itemRect!;
        RenderBox box = context.findRenderObject() as RenderBox;
        var local = box.globalToLocal(_offset);
        target.itemRect =
            Rect.fromLTWH(local.dx, local.dy, rect.width, rect.height);
        itemList.remove(target);
        itemList.insert(itemList.length, target);
        itemList.refresh();
        int i = 0;
        Timer.periodic(const Duration(milliseconds: 200), (Timer timer) {
          body.shakeColor = i % 2 == 0 ? 0xff5B9BD5 : 0xffD9DDE8;
          target.shakeColor = i % 2 == 0 ? 0xff5B9BD5 : 0xffD9DDE8;
          itemList.refresh();
          i++;
          if (i == 6) {
            timer.cancel();
            body.isVisible = false;
            target.isVisible = false;
            bool isOver = true;
            itemList.forEach((element) {
              if (element.isVisible!) isOver = false;
            });
            if (isOver) getAnswer(recordList.toString());
            itemList.refresh();
          }
        });
      } else {
        _playVanishSound(false);
        int i = 0;
        Timer.periodic(const Duration(milliseconds: 200), (Timer timer) {
          body.shakeColor = i % 2 == 0 ? 0xffff0000 : 0xffD9DDE8;
          target.shakeColor = i % 2 == 0 ? 0xffff0000 : 0xffD9DDE8;
          itemList.refresh();
          i++;
          if (i == 6) {
            timer.cancel();
          }
        });
      }
    }));
  }

  void _playVanishSound(bool isRight) {
    String path = isRight
        ? "assets/sound/vanishRight.mp3"
        : "assets/sound/vanishError.mp3";
    BGSinglePlayer().playByAsset(path);
  }
}
